Function: c-unmark-<>-around-region

c-unmark-<>-around-region is a byte-compiled function defined in cc-engine.el.gz.

Signature

(c-unmark-<>-around-region BEG END &optional OLD-LEN)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-engine.el.gz
(defun c-unmark-<>-around-region (beg end &optional old-len)
  ;; Unmark certain pairs of "< .... >" which are currently marked as
  ;; template/generic delimiters.  (This marking is via syntax-table text
  ;; properties), and expand the (c-new-BEG c-new-END) region to include all
  ;; unmarked < and > operators within the certain bounds (see below).
  ;;
  ;; These pairs are those which are in the current "statement" (i.e.,
  ;; the region between the {, }, or ; before BEG and the one after
  ;; END), and which enclose any part of the interval (BEG END).
  ;;
  ;; Note that in C++ (?and Java), template/generic parens cannot
  ;; enclose a brace or semicolon, so we use these as bounds on the
  ;; region we must work on.
  ;;
  ;; The buffer is widened, and point is undefined, both at entry and exit.
  ;;
  ;; FIXME!!!  This routine ignores the possibility of macros entirely.
  ;; 2010-01-29.

  (when (or old-len (> end beg))
    ;; Extend the region (BEG END) to deal with any complicating literals.
    (let* ((lit-search-beg (if (memq (char-before beg) '(?/ ?*))
			       (1- beg) beg))
	   (lit-search-end (if (memq (char-after end) '(?/ ?*))
			       (1+ end) end))
	   ;; Note we can't use c-full-pp-to-literal here, since we haven't
	   ;; yet applied syntax-table properties to ends of lines, etc.
	   (lit-search-beg-s (c-semi-pp-to-literal lit-search-beg))
	   (beg-literal-beg (car (cddr lit-search-beg-s)))
	   (lit-search-end-s (c-semi-pp-to-literal lit-search-end))
	   (end-literal-beg (car (cddr lit-search-end-s)))
	   (beg-literal-end (c-end-of-literal lit-search-beg-s lit-search-beg))
	   (end-literal-end (c-end-of-literal lit-search-end-s lit-search-end))
	   new-beg new-end search-region)

      ;; Determine any new end of literal resulting from the insertion/deletion.
      (setq search-region
	    (if (and (eq beg-literal-beg end-literal-beg)
		     (eq beg-literal-end end-literal-end))
		(if beg-literal-beg
		    nil
		  (cons beg
			(max end
			     (or beg-literal-end (point-min))
			     (or end-literal-end (point-min)))))
	      (cons (or beg-literal-beg beg)
		    (max end
			 (or beg-literal-end (point-min))
			 (or end-literal-end (point-min))))))

      (when search-region
	;; If we've just inserted text, mask its syntaxes temporarily so that
	;; they won't interfere with the undoing of the properties on the <s
	;; and >s.
	(c-save-buffer-state (syn-tab-settings syn-tab-value
					       swap-open-string-ends)
	  (unwind-protect
	      (progn
		(when old-len
		  ;; Special case: If a \ has just been inserted into a
		  ;; string, escaping or unescaping a LF, temporarily swap
		  ;; the LF's syntax-table text property with that of the
		  ;; former end of the open string.
		  (goto-char end)
		  (when (and (eq (cadr lit-search-beg-s) 'string)
			     (not (eq beg-literal-end end-literal-end))
			     (skip-chars-forward "\\\\")
			     (eq (char-after) ?\n)
			     (not (zerop (skip-chars-backward "\\\\")))
			     (< (point) end))
		    (setq swap-open-string-ends t)
		    (if (c-get-char-property (1- beg-literal-end)
					     'syntax-table)
			(progn
			  (c-clear-char-property (1- beg-literal-end)
						 'syntax-table)
			  (c-put-string-fence (1- end-literal-end)))
		      (c-put-string-fence (1- beg-literal-end))
		      (c-clear-char-property (1- end-literal-end)
					     'syntax-table)))

		  ;; Save current settings of the 'syntax-table property in
		  ;; (BEG END), then splat these with the punctuation value.
		  (goto-char beg)
		  (while (setq syn-tab-value
			       (c-search-forward-non-nil-char-property
				'syntax-table end))
		    (when (not (c-get-char-property (1- (point)) 'category))
		      (push (cons (1- (point)) syn-tab-value)
			    syn-tab-settings)))

		  (c-put-char-properties beg end 'syntax-table '(1))
		  ;; If an open string's opener has just been neutralized,
		  ;; do the same to the terminating LF.
		  (when (and (> end beg)
			     end-literal-end
			     (eq (char-before end-literal-end) ?\n)
			     (equal (c-get-char-property
				     (1- end-literal-end) 'syntax-table)
				    '(15)))
		    (push (cons (1- end-literal-end) '(15)) syn-tab-settings)
		    (c-put-char-property (1- end-literal-end) 'syntax-table
					 '(1))))

		(let
		    ((beg-lit-start (progn (goto-char beg) (c-literal-start)))
		     beg-limit end-limit <>-pos)
		  ;; Locate the earliest < after the barrier before the
		  ;; changed region, which isn't already marked as a paren.
		  (goto-char (or beg-lit-start beg))
		  (setq beg-limit (c-determine-limit 5000))

		  ;; Remove the syntax-table/category properties from each pertinent <...>
		  ;; pair.  Firstly, the ones with the < before beg and > after beg....
		  (goto-char (cdr search-region))
		  (while (progn (c-syntactic-skip-backward "^;{}<" beg-limit)
				(eq (char-before) ?<))
		    (c-backward-token-2)
		    (when (eq (char-after) ?<)
		      (when (setq <>-pos (c-clear-<-pair-props-if-match-after
					  (car search-region)))
			(setq new-end <>-pos))
		      (setq new-beg (point))))

		  ;; ...Then the ones with < before end and > after end.
		  (goto-char (car search-region))
		  (setq end-limit (c-determine-+ve-limit 5000))
		  (while (and (c-syntactic-re-search-forward "[;{}>]" end-limit 'end)
			      (eq (char-before) ?>))
		    (when (eq (char-before) ?>)
		      (if (and (looking-at c->-op-cont-regexp)
			       (not (eq (char-after) ?>)))
			  (goto-char (match-end 0))
			(when
			    (and (setq <>-pos
				       (c-clear->-pair-props-if-match-before
					(cdr search-region)
					(1- (point))))
				 (or (not new-beg)
				     (< <>-pos new-beg)))
			  (setq new-beg <>-pos))
			(when (or (not new-end) (> (point) new-end))
			  (setq new-end (point))))))))

	    (when old-len
	      (c-clear-char-properties beg end 'syntax-table)
	      (dolist (elt syn-tab-settings)
		(if (cdr elt)
		    (c-put-char-property (car elt) 'syntax-table (cdr elt)))))
	    ;; Swap the '(15) syntax-table property on open string LFs back
	    ;; again.
	    (when swap-open-string-ends
	      (if (c-get-char-property (1- beg-literal-end)
				       'syntax-table)
		  (progn
		    (c-clear-char-property (1- beg-literal-end)
					   'syntax-table)
		    (c-put-string-fence (1- end-literal-end)))
		(c-put-string-fence (1- beg-literal-end))
		(c-clear-char-property (1- end-literal-end)
				       'syntax-table)))))
	  ;; Extend the fontification region, if needed.
	  (and new-beg
	       (< new-beg c-new-BEG)
	       (setq c-new-BEG new-beg))
	  (and new-end
	       (> new-end c-new-END)
	       (setq c-new-END new-end))))))